package com.ght.springboot.rabbitmq;

import com.fasterxml.jackson.databind.deser.std.MapEntryDeserializer;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.springframework.cloud.stream.binder.rabbit.properties.RabbitCommonProperties.DEAD_LETTER_EXCHANGE;

/**
 * @description: RabbitMq配置
 * @author: haitao.gao
 * @create: 2019-01-09 11:37
 **/
@Configuration
public class RabbitmqConfiguration {


    @Value("${spring.rabbitmq.host:}")
    private String rabbitmqHost;

    @Value("${spring.rabbitmq.addresses:}")
    private String rabbitmqAddresses;

    @Value("${spring.rabbitmq.port}")
    private Integer rabbitmqPort;

    @Value("${spring.rabbitmq.username}")
    private String rabbitmqUsername;

    @Value("${spring.rabbitmq.password}")
    private String rabbitmqPassword;


//    public static final String routingKeyForOrderModuleCheckStockAndUpdateQueue =
//            "order-module-check-stock-and-update-routing-key";
//    public static final String routingKeyForOrderModuleAutoAsignQueue =
//            "order-module-auto-asign-routing-key";


    public static final String ExchangeDefault   = "test_direct_exchange";


    public static final String FanoutExchange = "test_fanout_exchange";

    /** 跨模块交换机 */
    private static final String ExchangeCrossModule =  "test_topic_exchange";

    private static final String Test01Queue = "test-01-queue";

    public static final String DeathLetterExchange = "test_death_exchange";

    private static final String DeathLetterRouting = "test_death_routing";

    private static final String TestDeathQueue = "test-death-queue";

    /** rabbitmq　连接对象 */
    @Bean
    public ConnectionFactory connectionFactoryForBusiness() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();

        if(StringUtils.isNotBlank(rabbitmqAddresses)){//生产环境或未来UAT环境, rabbitmq集群
            connectionFactory.setAddresses(rabbitmqAddresses);
        }else{
            connectionFactory.setHost(rabbitmqHost); //开发测试, 单台rabbitmq
        }
        connectionFactory.setPort(rabbitmqPort);
        connectionFactory.setUsername(rabbitmqUsername);
        connectionFactory.setPassword(rabbitmqPassword);
        connectionFactory.setPublisherConfirms(false); //必须要设置, 可以设置回调ack模式
        return connectionFactory;
    }

    /** 必须是prototype类型, 为每个线程生成一个对象, 主要是为了消息消费者(Listenner)能用不同的回调 */
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplateForBusiness() {
        RabbitTemplate template = new RabbitTemplate(connectionFactoryForBusiness());
        return template;
    }

    /**
     * 配置消息交换机
     * 针对消费者配置
     FanoutExchange: 将消息分发到所有的绑定队列，无routingkey的概念
     HeadersExchange ：通过添加属性key-value匹配
     DirectExchange:按照routingkey分发到指定队列
     TopicExchange:多关键字匹配
     */
    /**
     * 点对点 需要rounting_key
     */
    @Bean
    public DirectExchange defaultExchange() {
        return new DirectExchange(ExchangeDefault, true, false);//持久化消息, 消费后不删除
    }

    /**
     *
     * @return
     */
    @Bean
    public TopicExchange crossModuleExchange() {
        return new TopicExchange(ExchangeCrossModule, true, false);//持久化消息, 消费后不删除
    }

    /**
     * 点对边，自动发送到绑定Exchange所有的Queue
     */
    @Bean
    public FanoutExchange ignoreRoutingKeyExchange(){
        return  new FanoutExchange(FanoutExchange,true,false);
    }

    @Bean
    public DirectExchange deathLetterExchange(){
        return new DirectExchange(DeathLetterExchange,true,false);
    }

    /**
     * 订单补货检测消息队列
     * 针对消费者配置
     * @return
     */
    @Bean
    public Queue queue1() {

        Map<String,Object> args=new HashMap<>();
        // 设置该Queue的死信的信箱
        args.put("x-dead-letter-exchange",DeathLetterExchange);
//        // 设置死信routingKey
        args.put("x-dead-letter-routing-key",DeathLetterRouting);
        args.put("x-message-ttl",2000);

        return new Queue(Test01Queue, false,false,false,args); //队列持久
//        return new Queue(Test01Queue, true,false,false);

    }

    @Bean
    public Queue deathLetterQueue(){
        return new Queue(TestDeathQueue,true,false,false);
    }

    /**
     * 订单补货检测消息队列与交换机绑定
     * 针对消费者配置
     * @return
     */
    @Bean
    public Binding binding1() {
        return BindingBuilder.bind(queue1()).to(defaultExchange()).with("test-queue1-routing");
    }

    @Bean
    public Binding bindingDeath(){
        return BindingBuilder.bind(deathLetterQueue()).to(deathLetterExchange()).with("test_death_routing");
    }

//    @Bean
//    public Binding  binding3(List<String> test){
//        for(Map.Entry entry : args.entrySet()){
//
//        }
//        return BindingBuilder.bind(queue1())
//    }

}
